<?php
/*
 * 微信
 */
namespace Common\Logic;

class WxPayLogic{


    public $mchId;
    public $appId;
    public $appSecret;
    public $nounceStr;

    public function __construct()
    {
        $aWxConfig = C('wx_config');
        $this->mchId       = isset($aWxConfig['mchId']) && $aWxConfig['mchId'] ? $aWxConfig['mchId'] : '';
        $this->appId       = isset($aWxConfig['appId']) && $aWxConfig['appId'] ? $aWxConfig['appId'] : '';
        $this->appSecret   = isset($aWxConfig['appSecret']) && $aWxConfig['appSecret'] ? $aWxConfig['appSecret'] : '';
        $this->nounceStr   = isset($aWxConfig['nounceStr']) && $aWxConfig['nounceStr'] ? $aWxConfig['nounceStr'] : '';
    }

    /**
     * 获取微信jssdk的配置
     * @param string $sAccessUrl
     * @return array
     */
    public function JssdkConfig($sAccessUrl=''){
        $oRedisLogic    =   new \Common\Logic\RedisLogic();

        $sAccessToken   = $this->getAccessToken();

        $redis = $oRedisLogic->connect();
        $ticket = $redis->get('wx_ticket');
        if(empty($ticket)){
            $ticket_url    = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$sAccessToken";
            $res           = json_decode($this->https_request($ticket_url));
            $ticket        = isset($res->ticket) ? $res->ticket : "";
            $expires_in        = isset($res->expires_in) ? $res->expires_in : 7200;
            $redis->setex('wx_ticket', $expires_in, $ticket);
        }

        $url           = $sAccessUrl ? $sAccessUrl : SERVICE_URL . $_SERVER['REQUEST_URI'];
        $timestamp     = time();
        $nonceStr      = $this->nounceStr;
        return $this->getSignPackage($ticket, $url, $timestamp, $nonceStr);
    }


    /**
     * 处理微信的jssdk返回包
     * @param $ticket
     * @param $url
     * @param $timestamp
     * @param $nonceStr
     * @return array
     */
    public function getSignPackage($ticket, $url, $timestamp, $nonceStr)
    {
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string      = "jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature   = sha1($string);
        $signPackage = array(
            "appId"     => $this->appId,
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return $signPackage;
    }

    /**
     * 获取access_token；
     * @return string
     */
    public function getAccessToken()
    {
        $oRedisLogic    =   new \Common\Logic\RedisLogic();

        $redis = $oRedisLogic->connect();
        $sAccessToken = $redis->get('wx_access_token');
        if(empty($sAccessToken)){
            $get_token_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $this->appId  . '&secret=' . $this->appSecret;
            $json_obj      = json_decode($this->https_request($get_token_url), true);
            $sAccessToken   = isset($json_obj['access_token']) ? $json_obj['access_token'] : "";
            $expires_in = isset($json_obj['expires_in']) ? $json_obj['expires_in'] : 7200;
            $redis->setex('wx_access_token', $expires_in, $sAccessToken);
        }

        return $sAccessToken;
    }


    /**
     * 微信统一下单，获取prepay_id
     *
     * $order_data              //订单信息
     * $openid                  //用户微信$openid
     * $notify_url              //回调地址
     * $debug                   //是否开启调试模式，是=>支付金额0.01，否=>实际支付金额
     */
    public function getPrepayId($order_data,$openid,$notify_url,$debug=true)
    {

        $total = $order_data['pay_prices'];
        $out_trade_no = $order_data['order_no'];

        $description = '【融易找房】成功续费'.$order_data['count'].'月';
        if($order_data['order_type'] == \Common\Model\OrderModel::ORDER_TYPE_PORT){
            $description = '【融易找房】成功购买端口'.$order_data['port_count'].'个';
        }

        //开启调试模式，用户支付金额为0.01
        if($debug){
            $total = 0.01;
        }


        $total = bcmul($total,100,2);//因微信价格单位为分，而系统单位为元，所以需要转换


        //回调全地址拼接
        if(!stristr($notify_url,$_SERVER["SERVER_NAME"])){
            $notify_url = $_SERVER["REQUEST_SCHEME"].'://'.$_SERVER["SERVER_NAME"].'/'.$notify_url;
        }

        $aPrepayInfo = [
            'mchid' =>$this->mchId,
            'appid' =>$this->appId,
            'out_trade_no' =>   $out_trade_no,
            'description' =>   $description,
            'time_expire' =>    $this->mchId,
            'notify_url' => $notify_url,
            'amount' =>[
                'total' => $total,
                'currency' => "CNY"
            ],
            'payer' =>[
                'openid'=>  $openid
            ],
        ];

        $url = 'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi';
        $json_obj      = json_decode($this->https_request($url,$aPrepayInfo), true);

        $prepay_id   = isset($json_obj['prepay_id']) ? $json_obj['prepay_id'] : "";

        if(!empty($prepay_id)){
            return ['code'=>1,'data'=>[],'prepay_id'=>$prepay_id];
        }else{
            return ['code'=>-1,'data'=>$json_obj];
        }

    }


    /**
     * 发送http请求
     * @param $url
     * @param null $data
     * @return bool|string
     */
    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
}